package com.rest.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.build.model.AbstractBuilder;
import com.rest.model.HttpMethod;
import com.rest.model.Parameter;
import com.rest.model.RequestBuilderConfig;
import com.rest.model.RestRequest;
import com.rest.model.RestRequestBuilder;

public class RestRequestBuilderImpl extends AbstractBuilder<RestRequest, RequestBuilderConfig> implements RestRequestBuilder {

	private static final String CONTENT_TYPE_HEADER = "Content-Type";

	private static final String MULTIPART_CONTENT_TYPE = "multipart/form-data";

	private HttpMethod method;

	private String url;

	private final Map<String, String> headers = new HashMap<String, String>();

	private final List<Parameter<String>> queryParams = new ArrayList<Parameter<String>>();

	private final List<Parameter<Object>> formParams = new ArrayList<Parameter<Object>>();

	public RestRequestBuilderImpl(RequestBuilderConfig defaultConfig) {
		super(defaultConfig);
	}

	public RestRequest create() {

		if (method == null || url == null) {
			throw new IllegalStateException("Method and url cannot be null");
		}

		RestRequest request = null;
		String requestUrl = getRequestUrl();

		if (method == HttpMethod.POST && isMultipart()) {
			request = new RestMultipartRequest(requestUrl, headers, queryParams, formParams);
		} else {
			request = new RestScribeRequest(method, requestUrl, headers, queryParams, formParams);
		}
		return request;
	}

	public void setContentType(String contentType) {
		this.headers.put(CONTENT_TYPE_HEADER, contentType);
	}

	public void addHeader(String key, String value) {
		this.headers.put(key, value);
	}

	public void addQueryParam(String key, String value) {
		this.queryParams.add(new Parameter<String>(key, value));
	}

	public void addFormParam(String key, Object value) {
		this.formParams.add(new Parameter<Object>(key, value));
	}

	public void setMethod(HttpMethod method) {
		this.method = method;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	private boolean isMultipart() {

		boolean isMultipart = false;

		if (headers.containsKey(CONTENT_TYPE_HEADER)) {

			String contentType = headers.get(CONTENT_TYPE_HEADER);
			isMultipart = contentType.equals(MULTIPART_CONTENT_TYPE);
		}
		return isMultipart;
	}

	private String getRequestUrl() {
		RequestBuilderConfig config = this.getConfig();

		String path = config.getPath();
		if (!path.equals("") && !path.startsWith("/")) {
			path = "/" + path;
		}
		String serviceUrl = url;
		if (!serviceUrl.equals("") && !serviceUrl.startsWith("/")) {
			serviceUrl = "/" + serviceUrl;
		}
		return config.getScheme() + "://" + config.getHost() + path + serviceUrl;
	}
}
